﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Linq;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;
using GeneralDFS.DataEntity.IO;
namespace GeneralDFS.BusinessLogical.IO
{
    public class FileData
    {
        private static FileData instance;
        public static string FileDataPath;
        private FileStream fileStream;
        
        public FileData(string path)
        {
            FileDataPath = Path.Combine(path, "FileData");
            if (!System.IO.File.Exists(FileDataPath))
            {
                FileStream fs = System.IO.File.Create(FileDataPath);
                fs.Dispose();
            }
            fileStream = new FileStream(FileDataPath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
        }
        public static FileData GetInstance()
        {
            if (instance != null)
                return instance;
            throw new Exception("uninit instance");
        }
        public static void Init(string path)
        {
            instance = new FileData(path);
        }

        public byte[] GetSmallFileData(Guid guid)
        {
            lock (fileStream)
            {
                IndexFileInfo indexFileInfo = IndexFile.GetInstance().IndexFileTable[guid.ToString()] as IndexFileInfo;
                byte[] data = new byte[indexFileInfo.FileLength];
                fileStream.Seek(indexFileInfo.OffSet, SeekOrigin.Begin);
                int readLength = 0;
                while (readLength < indexFileInfo.FileLength)
                {
                    readLength += fileStream.Read(data, readLength, indexFileInfo.FileLength - readLength);
                }
                return data;

            }

        }

        public void AddFileToFileData(byte[] data, FileBlockMetaData fileBlockMetaData)
        {
            lock (fileStream)
            {
                fileStream.Seek(0, SeekOrigin.End);
                long offSet = fileStream.Length;
                Task task = fileStream.WriteAsync(data, 0, data.Length);
                IndexFileInfo indexFileInfo = new IndexFileInfo()
                    {
                        FileLength = (int)fileBlockMetaData.Length,
                        OffSet = offSet,
                        Valid = 1,
                    };
                IndexFile.GetInstance().AddNewFile(fileBlockMetaData.Guid.ToString(), indexFileInfo);
                task.Wait();
            }
        }
    }
}
